﻿#pragma once

#include "cocos2d.h"
extern "C" {
#include "../ifclient/packet.h"
}

USING_NS_CC;
using namespace std;

class Ifclient : public cocos2d::Ref
{
public:
	static Ifclient* create(const char *serverHost, unsigned short port, const char *username, const char *token, int encryptKey, int pingInteval);
	Ifclient(const char *serverHost, unsigned short port, const char *username, const char *token, int encryptKey, int pingInteval);
	~Ifclient();
	void setCallback(int mrcb, int ercb, int cscb, int cecb, int dcb);
	void connect(int timeout);

	// immediately为false:可能会出现，还在读取数据，结果断开了连接
	// 断开连接，先发送关闭会话消息，收到后在会调，如果网络不好，那么就可能收不到，这样你要超市处理
	// immediately为true:立即断开连接
	void disconnect(bool immediately);

	int getState();
	int getMsDelay();
	int getDownloadCount();
	int getUploadCount();
	unsigned short getPort();

	// 这下面的3个返回，你要知道，是不能被修改的，还有也是不用你去释放的，记住，不是你分配的char*，释放的时候，请万分小心
	char* getServerHost();
	char* getServerName();
	char* getLocalUsername();

	int sendMessage(const char *to, const char *resource, const char *title, const char *data, int id);
	int sendEvent(const char *to, const char *resource, byte type, short eventType, int action, const char *body, int id);

	void addFunction(std::function<void()> func);
private:
	void* session;

	// 回调函数定义
	int mcb;
	int ecb;
	int cscb;
	int cfcb;
	int dcb;
	
	static void messageRecvCallback(void *userdata, ifmessage *message);
	static void eventRecvCallback(void *userdata, ifevent *event);
	static void connectSuccessedCallback(void *userdata, char *extra);
	static void connectErrorCallback(void *userdata, int type, char *reason);
	static void disconnectCallback(void *userdata, char *reason);

	// 线程
	std::thread* thread;
	std::vector<std::function<void()>> functions;
	std::mutex function_mutex;
};